home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
PROGRAMR
/
TKERN091.ZIP
/
SRC
/
WINDOW.C
< prev
next >
Wrap
Text File
|
1994-03-17
|
30KB
|
1,384 lines
/*
* This file forms part of "TKERN" - "Troy's Kernel for Windows".
*
* Copyright (C) 1994 Troy Rollo <troy@cbme.unsw.EDU.AU>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <windows.h>
#include <windowsx.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/tfile.h>
#include <sys/tdevice.h>
#include <sys/tkwin.h>
static BOOL bRegistered = 0;
extern HINSTANCE hInstance;
extern int nError;
extern void UnlockManager(void);
extern void LockManager(void);
extern void FlushMessages(void);
extern void tkern_wakeup_call(void);
static int window_destroy(HWND hWnd);
#define SC_COPY 5000
#define SC_PASTE 5001
#define SC_COPYPASTE 5002
#define DEF_MAXLINES 100
#define DEF_SCROLLLINES 5
struct line
{
struct line *plNext;
struct line *plPrev;
char *pchLine;
};
struct per_window
{
struct line *pw_head;
struct line *pw_tail;
struct line *pw_inhead;
struct line *pw_intail;
struct line *pw_history;
struct line *pw_hishead;
struct line *pw_histail;
int nUnscrolledLines;
int nHistory;
int nHistMax;
int nScrollLines;
int nLines; /* Counter so we can keep the list reasonable */
int nLinesMax;
int cxChar;
int cyChar;
int nScrollPos;
HWND hEdit;
int xEditStart;
POINT ptMarkStart;
POINT ptMarkEnd;
BOOL bMarkValid;
BOOL bHaveMouse;
BOOL bProgramClosed;
};
#define ENTER_HIT WM_USER + 1000
#define UP_HIT WM_USER + 1001
#define DOWN_HIT WM_USER + 1002
WNDPROC NormalEditWndProc = 0;
FARPROC FakeEditThunk = 0;
int far pascal _export
FakeEditWndProc( HWND hWnd,
UINT wMsg,
WPARAM wParam,
LPARAM lParam)
{
if (wMsg == WM_KEYDOWN)
{
if (wParam == VK_UP)
{
SendMessage(GetParent(hWnd), UP_HIT, 0, 0);
return 0;
}
else if (wParam == VK_DOWN)
{
SendMessage(GetParent(hWnd), DOWN_HIT, 0, 0);
return 0;
}
}
if (wMsg == WM_CHAR)
{
if (wParam == VK_RETURN)
{
SendMessage(GetParent(hWnd), ENTER_HIT, 0, 0);
return 0;
}
else if (wParam == VK_TAB)
{
SendMessage(hWnd, EM_REPLACESEL, 0, (long) "\t");
return 0;
}
}
return (*NormalEditWndProc)(hWnd, wMsg, wParam, lParam);
}
static void
MoveMark(struct per_window *pw,
int nLines)
{
if (pw->bMarkValid)
{
pw->ptMarkStart.y += nLines;
pw->ptMarkEnd.y += nLines;
}
}
static void
screen_to_row( HWND hWnd,
struct per_window *pw,
int x,
int y,
int *xOut,
int *yOut)
{
RECT rcClient;
int cyLastRow;
struct line *pl;
int i, j;
GetClientRect(hWnd, &rcClient);
y = rcClient.bottom - y;
cyLastRow = pw->cyChar + pw->cyChar / 5 * 2;
if (y < cyLastRow)
{
*yOut = 0;
}
else
{
*yOut = (y - cyLastRow) / pw->cyChar + 1;
}
if (*yOut > 0)
*yOut += pw->nScrollPos;
for (i = *yOut, pl = pw->pw_tail;
i && pl;
i--, pl = pl->plPrev);
if (!pl || !pl->pchLine)
{
*xOut = 0;
return;
}
x = x / pw->cxChar;
for (i = j = 0; x > j && pl->pchLine[i]; i++)
{
if (pl->pchLine[i] == '\t')
j += 8 - j % 8;
else
j++;
}
*xOut = i;
}
static void
RedrawPoints( HWND hWnd,
struct per_window *pw,
POINT ptStart_,
POINT ptEnd_)
{
POINT ptStart, ptEnd;
RECT rcRedraw;
if (ptStart_.y > ptEnd_.y)
{
ptStart = ptStart_;
ptEnd = ptEnd_;
}
else if (ptStart_.y < ptEnd_.y)
{
ptStart = ptEnd_;
ptEnd = ptStart_;
}
else if (ptStart_.x < ptEnd_.x)
{
ptStart = ptStart_;
ptEnd = ptEnd_;
}
else
{
ptStart = ptEnd_;
ptEnd = ptStart_;
}
if (ptEnd.y > 0)
{
ptEnd.y -= pw->nScrollPos;
if (ptEnd.y < 0)
ptEnd.y = 0;
}
if (ptStart.y > 0)
{
ptStart.y -= pw->nScrollPos;
if (ptStart.y < 1)
ptStart.y = 1;
}
if (ptStart.y < ptEnd.y)
return;
GetClientRect(hWnd, &rcRedraw);
rcRedraw.top = rcRedraw.bottom - pw->cyChar * (ptStart.y + 1) - pw->cyChar / 5 * 2;
if (ptEnd.y)
rcRedraw.bottom -= pw->cyChar * ptEnd.y + pw->cyChar / 5 * 2;
InvalidateRect(hWnd, &rcRedraw, TRUE);
}
static void
MouseDown( HWND hWnd,
struct per_window *pw,
int x,
int y)
{
if (pw->bMarkValid)
{
pw->bMarkValid = FALSE;
RedrawPoints(hWnd, pw, pw->ptMarkStart, pw->ptMarkEnd);
}
screen_to_row(hWnd, pw, x, y, &pw->ptMarkStart.x, &pw->ptMarkStart.y);
pw->ptMarkEnd = pw->ptMarkStart;
RedrawPoints(hWnd, pw, pw->ptMarkStart, pw->ptMarkEnd);
SetCapture(hWnd);
pw->bHaveMouse = TRUE;
pw->bMarkValid = TRUE;
}
static void
MouseMove( HWND hWnd,
struct per_window *pw,
int x,
int y)
{
POINT ptTemp;
ptTemp = pw->ptMarkEnd;
screen_to_row(hWnd, pw, x, y, &pw->ptMarkEnd.x, &pw->ptMarkEnd.y);
RedrawPoints(hWnd, pw, ptTemp, pw->ptMarkEnd);
}
static void
MouseUp(struct per_window *pw)
{
ReleaseCapture();
pw->bHaveMouse = FALSE;
}
static void
get_mark_coordinates( struct per_window *pw,
POINT *ptOne,
POINT *ptTwo)
{
if (pw->ptMarkStart.y > pw->ptMarkEnd.y)
{
*ptOne = pw->ptMarkStart;
*ptTwo = pw->ptMarkEnd;
}
else if (pw->ptMarkStart.y < pw->ptMarkEnd.y)
{
*ptOne = pw->ptMarkEnd;
*ptTwo = pw->ptMarkStart;
}
else if (pw->ptMarkStart.x < pw->ptMarkEnd.x)
{
*ptOne = pw->ptMarkStart;
*ptTwo = pw->ptMarkEnd;
}
else
{
*ptOne = pw->ptMarkEnd;
*ptTwo = pw->ptMarkStart;
}
}
static int
is_in_mark( int iRow,
struct per_window *pw,
int *iMarkBoundary1,
int *iMarkBoundary2)
{
POINT ptStart, ptEnd;
if (!pw->bMarkValid)
return 0;
get_mark_coordinates(pw, &ptStart, &ptEnd);
if (ptStart.y > ptEnd.y)
{
if (ptEnd.y > iRow ||
ptStart.y < iRow)
return 0;
if (ptStart.y == iRow)
{
*iMarkBoundary1 = ptStart.x;
return 1;
}
if (ptEnd.y == iRow)
{
*iMarkBoundary1 = ptEnd.x;
return 2;
}
return 3;
}
else if (ptStart.y == iRow)
{
*iMarkBoundary1 = ptStart.x;
*iMarkBoundary2 = ptEnd.x;
return 4;
}
else
{
return 0;
}
}
static void
PlaceEdit( HWND hWnd,
struct per_window *pw)
{
RECT rcLoc;
GetClientRect(hWnd, &rcLoc);
rcLoc.left = pw->xEditStart;
rcLoc.top = rcLoc.bottom - pw->cyChar - pw->cyChar / 5;
if (pw->hEdit)
{
MoveWindow(pw->hEdit,
rcLoc.left, rcLoc.top,
rcLoc.right - rcLoc.left + 1,
rcLoc.bottom - rcLoc.top + 1,
TRUE);
}
else
{
pw->hEdit = CreateWindow( "EDIT",
"",
WS_VISIBLE |
WS_CHILD |
ES_AUTOHSCROLL |
ES_LEFT,
rcLoc.left,
rcLoc.top,
rcLoc.right - rcLoc.left,
rcLoc.bottom - rcLoc.top,
hWnd,
(HMENU) 100,
hInstance,
0
);
if (!NormalEditWndProc)
{
NormalEditWndProc = (WNDPROC)
GetWindowLong(pw->hEdit, GWL_WNDPROC);
}
if (!FakeEditThunk)
{
FakeEditThunk = MakeProcInstance((FARPROC) FakeEditWndProc, hInstance);
}
SetWindowLong(pw->hEdit, GWL_WNDPROC, (long) FakeEditThunk);
}
}
static void
PaintWindow( HWND hWnd,
struct per_window *pw)
{
PAINTSTRUCT ps;
TEXTMETRIC tm;
LOGFONT lf;
int cyChar;
int cyInch;
int yLocation;
int nRows;
RECT rcClient;
HFONT hFont, hOldFont;
int iRow, iTemp, iTotal;
struct line *pl;
LONG xExtent, xExtent2;
BOOL bBottom = TRUE;
int iMarkBoundary1, iMarkBoundary2;
COLORREF crBG, crFG, crFGHigh, crBGHigh;
crFG = GetSysColor(COLOR_WINDOWTEXT);
crBG = GetSysColor(COLOR_WINDOW);
crFGHigh = GetS